package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.utils.BooleanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.constants.RedisConstants;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.tianji.remark.service.ILikedStatService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
public class LikedRecordServiceRedisImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper mqHelper;
    private final StringRedisTemplate redisTemplate;
    private final ILikedStatService statService;


    /**
     * 添加点赞记录
     *
     * @param dto
     */
    @Override
    public void addLike(LikeRecordFormDTO dto) {
        Long userId = UserContext.getUser();
        String key = RedisConstants.LIKE_BIZ_KEY_PREFIX + dto.getBizId();
        String value = userId.toString();
        Long result = 0L;
        //判断是点赞还是取消点赞
        if (dto.getLiked()) {
            //添加点赞 利用set  -key(业务id) -value (用户id)可以自动去重,自动判断重复点赞
            result = redisTemplate.opsForSet().add(key, value);
        } else {
            //取消点赞 删除vulue中的当前用户的userid
            result = redisTemplate.opsForSet().remove(key, value);
        }
        if (result == null || result == 0) {
            return;
        }

        Long size = redisTemplate.opsForSet().size(key);
        if (size==null){
            return;
        }
        key= RedisConstants.LIKE_COUNT_KEY_PREFIX + dto.getBizType();
        value=dto.getBizId().toString();
        //统计保存点赞数量 利用zset -key (业务类型)  -value(业务id)  -sorce (点赞数量)
        redisTemplate.opsForZSet().add(key, value, size.doubleValue());

    }

    /**
     * 查询点赞列表
     *
     * @param bizIds
     * @return
     */
    @Override
    public Set<Long> isBizLiked(List<Long> bizIds) {

        //管道操作,避免多次连接redis的io操作耗时
        //收集的是每次命令的返回值
        List<Object> objects = redisTemplate.executePipelined((RedisCallback<?>) (connection -> {
            StringRedisConnection conn = (StringRedisConnection) connection;
            String key = RedisConstants.LIKE_BIZ_KEY_PREFIX;
            Long userId = UserContext.getUser();
            for (Long bizId : bizIds) {
                key = key + bizId;
                conn.sIsMember(key, userId.toString());
            }
            return null;//表示连接对象的返回值
        }));

        //找到点过赞的bizid ,也是集合中的对应true的下标
        Set<Long> longs = new HashSet<>();
        for (int i = 0; i < objects.size(); i++) {
            Boolean o = (Boolean) objects.get(i);
            if (BooleanUtils.isTrue(o)) {
                longs.add(bizIds.get(i));
            }
        }
        //第二种方法
        List<Long> collect = IntStream.range(0, objects.size())
                .filter(x -> BooleanUtils.isTrue((Boolean) objects.get(x)))
                .mapToObj(bizIds::get).collect(Collectors.toList());

        return longs;
    }
}